#ifndef FONCTIONS_H
#define FONCTIONS_H

#include <stdio.h>
#include "table_symboles.h"

extern FILE *yyout;

// un quadruplet que l'on stock car on a pas encore la valeur de l'etiquette
typedef struct quad {
    int oper;
    char *arg1;
    char *arg2;
    // l'etiquete de branchement est dans le res, null au depart
    char *res;
    int type;
    int arg1_pointeur;
    int arg2_pointeur;
    int res_pointeur;
    // on chaine les quad
    int index;
} s_quad;

// chainage hors du quad, permet d'avoir plusieurs listes de quad
typedef struct quad_element {
    struct quad_element *previous;
    s_quad *quad;
    struct quad_element *next;
} s_quad_elem;

// la liste de quad qui sert a stocker les futures instructions générés
typedef struct quadl {
    s_quad_elem *first;
    s_quad_elem *last;
} list_quad;

// expression du code
typedef struct expression {
    char *ptr;
    int type;
    int pointeur;
    list_quad *true;
    list_quad *false;
    list_quad *next;
    int quad;
} s_expression;

typedef struct ident {
    char *name;
    int pointeur;
} s_ident;

// element de la liste des quad qui prennent un label
typedef struct label {
    int num_quad;
    struct label *previous;
    struct label *next;
} s_label;

// liste des quad qui prennent un label
typedef struct list_labels {
    struct label *first;
    struct label *last;
} s_list_labels;

char in[100];
char out[100];

char operation[500][6];

// la liste de quad principaux
list_quad *liste_quad;

s_table *table_int;
s_table *table_float;
s_table *table_pointeur;
s_table *table_string;

s_list_labels *labels;

// utiliser pour les valeurs booleennes
s_expression *assert;
s_expression *increment_int;
s_expression *decrement_int;
s_expression *increment_float;
s_expression *decrement_float;

// ecrit la ligne dans le fichier de sortie
void ecrire(const char *);

void start();
void end();
char* out_file( char* );

s_expression *newstring(char *valeur);
s_expression *newint(int valeur);
s_expression *newfloat(float valeur);

s_expression *newtmp(int);
s_expression *newtmpint();
s_expression *newtmpfloat();
s_expression *id(s_ident *);

s_quad * get_quad( int );
s_quad *gencode(int, const char *, const char *, const char *, int);
s_quad *gencode_pointer(int, const char *, const char *, const char *, int, int, int, int);

void add_label(int);
int is_label(int);

int gencode_final(s_quad *q);
list_quad *creeListe( s_quad* );
void complete( list_quad *, int );
list_quad *concat( list_quad*, list_quad* );
int nextquad();

void afficher_listequad();
void afficher_liste( list_quad* );

#endif
